# Copyright (c) 2021 Contributors to the Eclipse Foundation
# 
# See the NOTICE file(s) distributed with this work for additional
# information regarding copyright ownership.
# 
# This program and the accompanying materials are made available under the
# terms of the Eclipse Public License 2.0 which is available at
# http://www.eclipse.org/legal/epl-2.0
# 
# SPDX-License-Identifier: EPL-2.0
#
import os
import re
import pathlib
import datetime
import xml.etree.ElementTree as ET
import html

import nut_utils

def mkPackagePath(outbasedir, packagename, replace_filename_vars, lang):
    pkgpath = outbasedir +'/'+re.sub('\.','/', packagename)

    if replace_filename_vars:
        pkgpath = nut_utils.parseFileNameForLangVars(pkgpath, lang)

    pathlib.Path(pkgpath).mkdir(parents=True, exist_ok=True)
    
def getOutputPath(outbasedir, packagename, classname, replace_filename_vars, lang):
    pkgpath = outbasedir +'/'+re.sub('\.','/', packagename)
    
    outpath =  pkgpath+'/'+classname+'.java'
    
    if replace_filename_vars:
        outpath = nut_utils.parseFileNameForLangVars(outpath, lang)

    return outpath
    
def msgTextNodeToLRBString(xmlnode):
    '''The node can contain innertext and tags like <q />'''
    strwithtags = ET.tostring(xmlnode).decode()
    
    #Replace <q />'s with double-quotes
    str1      = re.sub("<\s*q[\s/]*>",'\\"',strwithtags)
    #Replace line breaks with spaces
    str2      = re.sub("\n",' ',str1)
    #Replace <br /> tags
    str3      = re.sub("<\s*br[\s/]*>",'\\\\n',str2)
    #Remove starting tag
    str4  = re.sub("<\s*MsgText[^>]*>",'',str3)
    #Remove ending tag
    str5  = re.sub("<\s*/\s*MsgText[^>]*>",'',str4)
    
    #Replace xml angled brackets etc for the real thing
    str6 = html.unescape(str5)
     
    #Unlike ICU we do NOT duplicate single quotes- so not str7 needed
    
    #Surprisingly (to me) - replace any number of spaces with a single space
    str8 = re.sub("\s{2,}", ' ', str6)
    
    return str8.strip()

def writeClassIntro(outfile, packagename,classname):
    outfile.write("public class "+classname+" extends java.util.ListResourceBundle\n")
    outfile.write("{\n")
    outfile.write("    /** COPYRIGHT */\n")
    outfile.write('    public static final String COPYRIGHT= "************************************************************* (C) Copyright Contributors to the Eclipse Foundation 2012-2021 *************************************************************"; //$NON-NLS-1$\n')
    outfile.write("\n")
    outfile.write("    /** This static member defines the class name */\n")
    outfile.write('    public static final String CLASS_NAME = "'+packagename+'.'+classname+'"; //$NON-NLS-1$\n')
    outfile.write("\n")
    outfile.write("    /*********************************************************\n")
    outfile.write("    * Implements java.util.ListResourceBundle.getContents().\n")
    outfile.write("    *\n")
    outfile.write("    * @see java.util.ListResourceBundle#getContents()\n")
    outfile.write("    * @return Object[][]\n")
    outfile.write("    **********************************************************/\n")
    outfile.write("    public Object[][] getContents()\n")
    outfile.write("    {\n")
    outfile.write("        return CONTENTS;\n")
    outfile.write("    }\n")
    outfile.write("\n")
    outfile.write("\n")
    outfile.write("    /*********************************************************\n")
    outfile.write("    * Keys for translatable text\n")
    outfile.write("    **********************************************************/\n\n")


def outputLRBFile(logger, inputxmlroot, inputfile, outpath, packagename, classname):
    timestr = datetime.datetime.now().strftime("%H:%M:%S on %d %B %Y")
    logger.info("Converting "+inputfile+" to LRB output file: "+outpath+" at "+timestr)

    try:
        outfile = open(outpath, "w", encoding="utf8")
        outfile.write("//LRB output file generated by nut_genLRB.py (part of nut_translation.py)\n")
        outfile.write("//Generated from "+inputfile+" at "+timestr+"\n//\n\n")
   
        outfile.write("package "+packagename+";\n\n")
        writeClassIntro(outfile, packagename,classname)
   
        #The messages appear twice, one as string constants and again as part of the resoure table.
        #We write the first occurance to the file directly and build up a string for all messages
        #for the resource table that we write at the end
   
        resourcetablestring  = "    /*********************************************************\n"
        resourcetablestring += "    * Resource table\n"
        resourcetablestring += "    **********************************************************/\n"
        resourcetablestring += "    private final static Object[][] CONTENTS=\n"
        resourcetablestring += "    {\n"
   
        for child in inputxmlroot:
            if child.tag == "Message":
                msgnode = child
                msgid = None
                msgtext = None
                if msgnode.attrib['ID']:
                    msgid = msgnode.attrib['ID']
                for mchild in msgnode:
                    if mchild.tag == "MsgText":
                        msgtextnode = mchild
                        msgtext = msgTextNodeToLRBString(msgtextnode)
           
                if msgtext and msgid:
                    outfile.write("    /** This member defines a static reference to a key */ \n")
                    outfile.write('    public static final String '+msgid+' = "'+msgid+'"; //$NON-NLS-1$\n\n')
               
                    resourcetablestring += '        {'+msgid+', "'+msgtext+'"}, //$NON-NLS-1$\n'
                else:
                    logger.error("Malformed message")
                    if msgid:
                        logger.error("Maformed message ID is "+msgid)
                    else:
                        logger.error("Maformed message ID is MISSING")
                    if msgtext:
                        logger.error("Maformed message text is "+msgtext)
                    else:
                        logger.error("Maformed message text is MISSING")
   
        #Now we've written out all the message ids... put the resource table into the file                 
        resourcetablestring += '    };\n'
        outfile.write("\n")
        outfile.write(resourcetablestring)
   
        #and now file outro
        outfile.write("}\n\n\n")
        outfile.close()
    except Exception as e:
        logger.error("Failed to write LRB txt file: %s - error %s" %
                     (outpath,  e))
        raise e 

def outputLRB(logger, replace_filename_vars, infile, langliststr, outbasedir, pkgname, clssname):

    if langliststr is not None:
        langlist = nut_utils.parseLanguageLists(langliststr)

        for lang in langlist:
        
            if replace_filename_vars:
                inputfile   = nut_utils.parseFileNameForLangVars(infile, lang)
                packagename = nut_utils.parseFileNameForLangVars(pkgname, lang)
                classname   = nut_utils.parseFileNameForLangVars(clssname, lang)
            else:
                inputfile = infile
                packagename = pkgname
                classname = clssname
        
            inputxmlroot = nut_utils.parseFile(inputfile)

            mkPackagePath(outbasedir, packagename, replace_filename_vars, lang)
    
            outpath = getOutputPath(outbasedir, packagename, classname, replace_filename_vars, lang)
            
            outputLRBFile(logger, inputxmlroot, inputfile, outpath, packagename, classname)
    else:
        inputxmlroot = nut_utils.parseFile(infile)

        mkPackagePath(outbasedir, pkgname, False, None)
    
        outpath = getOutputPath(outbasedir, pkgname, clssname, False, None)
            
        outputLRBFile(logger, inputxmlroot, infile, outpath, pkgname, clssname)
    


